#ifndef UNIFIED_MEMORY_MANAGER_IMPL_H
#define UNIFIED_MEMORY_MANAGER_IMPL_H
#include "unified_memory_interfaces.h"
#include <QHash>
#include <QTimer>
#include <QThreadPool>
#include <QMutex>
#include <QMutexLocker>
#include <QElapsedTimer>
// TDD: 最小实现让测试通过
// 🟢 GREEN: 基础缓存项实现
class BasicCacheItem : public ICacheItem {
private:
    int m_index;
    QImage m_image;
    QDateTime m_lastAccessed;
    size_t m_memorySize;
public:
    BasicCacheItem(int index, const QImage& image)
        : m_index(index), m_image(image), m_lastAccessed(QDateTime::currentDateTime()) {
        m_memorySize = image.sizeInBytes();
    }
    int getIndex() const override { return m_index; }
    QImage getImage() const override { return m_image; }
    size_t getMemorySize() const override { return m_memorySize; }
    QDateTime getLastAccessed() const override { return m_lastAccessed; }
    void markAccessed() override { m_lastAccessed = QDateTime::currentDateTime(); }
    bool isLoaded() const override { return !m_image.isNull(); }
};
// 🟢 GREEN: 实际的统一缓存加载服务
class UnifiedCacheLoadingService : public ICacheLoadingService {
private:
    mutable QMutex m_mutex;
    mutable int m_callCount = 0;  // TDD: 用于验证调用次数
public:
    LoadResult loadFromCache(const QString& fileIdentity, int pageIndex) override {
        QMutexLocker locker(&m_mutex);
        m_callCount++;
        LoadResult result;
        result.loadTime = QDateTime::currentDateTime();
        try {
            // 使用现有的缓存路径逻辑
            QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
            QString cacheDir = UnifiedCacheManager::instance()->getCacheDirectory() + "/" + cacheKey;
            QString fileName = QString("page_%1.png").arg(pageIndex, 5, 10, QChar('0'));
            QString filePath = cacheDir + "/" + fileName;
            if (QFile::exists(filePath)) {
                QImage image(filePath);
                if (!image.isNull()) {
                    result.image = image;
                    result.success = true;
                    result.memoryUsed = image.sizeInBytes();
                } else {
                    result.errorMessage = "Image file corrupted";
                }
            } else {
                result.errorMessage = "Cache file not found";
            }
        } catch (const std::exception& e) {
            result.errorMessage = QString("Exception: %1").arg(e.what());
        }
        return result;
    }
    bool isCacheAvailable(const QString& fileIdentity, int pageIndex) const override {
        QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
        QString cacheDir = UnifiedCacheManager::instance()->getCacheDirectory() + "/" + cacheKey;
        QString fileName = QString("page_%1.png").arg(pageIndex, 5, 10, QChar('0'));
        QString filePath = cacheDir + "/" + fileName;
        return QFile::exists(filePath);
    }
    // TDD: 测试辅助方法
    int getCallCount() const { 
        QMutexLocker locker(&m_mutex);
        return m_callCount; 
    }
    void resetCallCount() { 
        QMutexLocker locker(&m_mutex);
        m_callCount = 0; 
    }
};
// 🟢 GREEN: 简单的内存管理器实现
class BasicUnifiedMemoryManager : public QObject, public IUnifiedMemoryManager {
    Q_OBJECT
private:
    struct MemoryPool {
        ContentType type;
        size_t maxMemory;
        size_t currentUsage = 0;
        QMap<int, std::unique_ptr<ICacheItem>> items;  // 使用QMap替代QHash，支持unique_ptr
        std::unique_ptr<IMemoryStrategy> strategy;
        int currentFocus = -1;
    };
    QMap<ContentType, std::unique_ptr<MemoryPool>> m_pools;  // 使用QMap替代QHash
    std::unique_ptr<ICacheLoadingService> m_cacheService;
    std::unique_ptr<IMemoryMonitor> m_memoryMonitor;
    std::unique_ptr<IPerformanceProfiler> m_profiler;
    mutable QMutex m_mutex;
    QString m_currentFileIdentity;  // 当前文件标识
public:
    explicit BasicUnifiedMemoryManager(QObject* parent = nullptr)
        : QObject(parent) {
        // 依赖注入：可以在测试中替换为Mock
        m_cacheService = std::make_unique<UnifiedCacheLoadingService>();
        m_memoryMonitor = std::make_unique<MockMemoryMonitor>();
        m_profiler = std::make_unique<BasicPerformanceProfiler>(m_memoryMonitor.get());
    }
    // 依赖注入构造函数（用于测试）
    BasicUnifiedMemoryManager(std::unique_ptr<ICacheLoadingService> cacheService,
                             std::unique_ptr<IMemoryMonitor> memoryMonitor,
                             std::unique_ptr<IPerformanceProfiler> profiler,
                             QObject* parent = nullptr)
        : QObject(parent),
          m_cacheService(std::move(cacheService)),
          m_memoryMonitor(std::move(memoryMonitor)),
          m_profiler(std::move(profiler)) {}
    void registerPool(ContentType type, size_t maxMemoryBytes) override {
        QMutexLocker locker(&m_mutex);
        auto pool = std::make_unique<MemoryPool>();
        pool->type = type;
        pool->maxMemory = maxMemoryBytes;
        pool->strategy = createDefaultStrategy(type);
        m_pools[type] = std::move(pool);
    }
    QImage getImage(ContentType type, int index, int currentFocus = -1) override {
        QMutexLocker locker(&m_mutex);
        auto* pool = getPool(type);
        if (!pool) {
            return QImage();
        }
        // 检查内存中是否已有
        auto it = pool->items.find(index);
        if (it != pool->items.end() && (*it)->isLoaded()) {
            (*it)->markAccessed();
            return (*it)->getImage();
        }
        // 不在内存中，从缓存加载
        QString fileIdentity = getCurrentFileIdentity();
        auto loadResult = m_cacheService->loadFromCache(fileIdentity, index);
        if (loadResult.success) {
            // 添加到内存池
            auto cacheItem = std::make_unique<BasicCacheItem>(index, loadResult.image);
            QImage result = cacheItem->getImage();
            pool->currentUsage += cacheItem->getMemorySize();
            pool->items[index] = std::move(cacheItem);
            // 检查是否需要清理内存
            managePoolMemory(pool, currentFocus);
            return result;
        }
        // 加载失败，返回占位符
        return createPlaceholder(type);
    }
    void setCurrentFocus(ContentType type, int focus) override {
        QMutexLocker locker(&m_mutex);
        auto* pool = getPool(type);
        if (pool) {
            pool->currentFocus = focus;
            managePoolMemory(pool, focus);
        }
    }
    size_t getMemoryUsage(ContentType type) const override {
        QMutexLocker locker(&m_mutex);
        auto* pool = getPool(type);
        return pool ? pool->currentUsage : 0;
    }
    void setMemoryStrategy(ContentType type, std::unique_ptr<IMemoryStrategy> strategy) override {
        QMutexLocker locker(&m_mutex);
        auto* pool = getPool(type);
        if (pool) {
            pool->strategy = std::move(strategy);
        }
    }
    // 设置当前文件标识
    void setCurrentFileIdentity(const QString& fileIdentity) {
        QMutexLocker locker(&m_mutex);
        m_currentFileIdentity = fileIdentity;
    }
private:
    MemoryPool* getPool(ContentType type) const {
        auto it = m_pools.find(type);
        return it != m_pools.end() ? it->get() : nullptr;
    }
    void managePoolMemory(MemoryPool* pool, int currentFocus) {
        if (pool->currentUsage <= pool->maxMemory) {
            return;  // 内存使用在限制内
        }
        // 收集所有项目
        QList<ICacheItem*> items;
        for (auto& item : pool->items) {
            items.append(item.get());
        }
        // 使用策略决定清理
        double memoryPressure = m_memoryMonitor->getMemoryPressure();
        auto decision = pool->strategy->makeEvictionDecision(
            items, currentFocus, pool->maxMemory, pool->currentUsage, memoryPressure);
        // 执行清理
        for (int index : decision.itemsToEvict) {
            auto it = pool->items.find(index);
            if (it != pool->items.end()) {
                pool->currentUsage -= (*it)->getMemorySize();
                pool->items.erase(it);
            }
        }
    }
    std::unique_ptr<IMemoryStrategy> createDefaultStrategy(ContentType type) {
        // 为不同类型创建默认策略
        switch (type) {
            case ContentType::MAIN_PAGE:
                return std::make_unique<DistanceBasedStrategy>(15);
            case ContentType::THUMBNAIL:
                return std::make_unique<VisibilityBasedStrategy>(50);
            case ContentType::COMPOSED_PAGE:
                return std::make_unique<LRUStrategy>();
        }
        return nullptr;
    }
    QImage createPlaceholder(ContentType type) {
        switch (type) {
            case ContentType::MAIN_PAGE:
                return QImage(1240, 1754, QImage::Format_RGB32);
            case ContentType::THUMBNAIL:
                return QImage(200, 200, QImage::Format_RGB32);
            case ContentType::COMPOSED_PAGE:
                return QImage(1240, 2000, QImage::Format_RGB32);
        }
        return QImage();
    }
    QString getCurrentFileIdentity() const {
        QMutexLocker locker(&m_mutex);
        return m_currentFileIdentity;
    }
};
// 🟢 GREEN: 基础性能分析器
class BasicPerformanceProfiler : public IPerformanceProfiler {
private:
    struct Operation {
        QElapsedTimer timer;
        size_t memoryBefore = 0;
        int callCount = 0;
        int successCount = 0;
        double totalTimeMs = 0.0;
        size_t totalMemoryDelta = 0;
    };
    mutable QMutex m_mutex;
    QHash<QString, Operation> m_operations;
    IMemoryMonitor* m_memoryMonitor;
public:
    explicit BasicPerformanceProfiler(IMemoryMonitor* monitor = nullptr)
        : m_memoryMonitor(monitor) {}
    void startOperation(const QString& operation) override {
        QMutexLocker locker(&m_mutex);
        auto& op = m_operations[operation];
        op.timer.start();
        if (m_memoryMonitor) {
            op.memoryBefore = m_memoryMonitor->getCurrentMemoryUsage();
        }
    }
    void endOperation(const QString& operation, bool success) override {
        QMutexLocker locker(&m_mutex);
        auto it = m_operations.find(operation);
        if (it != m_operations.end()) {
            auto& op = it.value();
            double elapsed = op.timer.elapsed();
            op.totalTimeMs += elapsed;
            op.callCount++;
            if (success) {
                op.successCount++;
            }
            if (m_memoryMonitor) {
                size_t memoryAfter = m_memoryMonitor->getCurrentMemoryUsage();
                op.totalMemoryDelta += (memoryAfter - op.memoryBefore);
            }
        }
    }
    OperationMetrics getMetrics(const QString& operation) const override {
        QMutexLocker locker(&m_mutex);
        auto it = m_operations.find(operation);
        if (it == m_operations.end()) {
            return OperationMetrics{operation, 0, 0, 0, 0};
        }
        const auto& op = it.value();
        OperationMetrics metrics;
        metrics.operation = operation;
        metrics.callCount = op.callCount;
        if (op.callCount > 0) {
            metrics.avgTimeMs = op.totalTimeMs / op.callCount;
            metrics.avgMemoryDelta = op.totalMemoryDelta / op.callCount;
            metrics.successRate = double(op.successCount) / op.callCount;
        }
        return metrics;
    }
    void generateReport() override {
        QMutexLocker locker(&m_mutex);
        for (auto it = m_operations.begin(); it != m_operations.end(); ++it) {
            auto metrics = getMetrics(it.key());
        }
    }
};
// 🟢 GREEN: RAII性能分析器
class ScopedProfiler {
private:
    IPerformanceProfiler* m_profiler;
    QString m_operation;
public:
    ScopedProfiler(IPerformanceProfiler* profiler, const QString& operation)
        : m_profiler(profiler), m_operation(operation) {
        if (m_profiler) {
            m_profiler->startOperation(m_operation);
        }
    }
    ~ScopedProfiler() {
        if (m_profiler) {
            m_profiler->endOperation(m_operation, true);
        }
    }
    void markFailure() {
        if (m_profiler) {
            m_profiler->endOperation(m_operation, false);
        }
    }
};
// 宏定义简化使用
#define PROFILE_MEMORY_OPERATION(profiler, operation) \
    ScopedProfiler _scoped_profiler(profiler, operation)
// 包含策略实现
#include "memory_strategies.h"
#endif // UNIFIED_MEMORY_MANAGER_IMPL_H
